<?php

class Comment extends CActiveRecord
{
    CONST CONTENT_MIN_LEN = 1;
    CONST CONTENT_MAX_LEN = 500;

    public static $autoLoadAttributes=array('id','recipeId','userId','userName');
    
    private $_saveAttributes;

    
    /********************************************************************
    *  Below are class functions
    *  WARNING: You should only use these functions to manipulate 
    *           the object instead of AR functions.
    *********************************************************************/

    public static function loadObjectById($id, $attributes='*')
    {
        if(is_array($attributes)){
            $attributes=array_unique(array_merge($attributes,self::$autoLoadAttributes));
        }
        return self::loadObject(array(
            'condition'=>'id=:id',
            'params'=>array(':id'=>$id),
            'select'=>$attributes,
        ));
    }
    
    public static function loadObjectsByRecipeId($recipeId, $options=array())
    {
        if($options instanceof CDbCriteria) {
            $criteria=&$options;            
        }
        else {
            $criteria=new CDbCriteria($options);
        }

        if(is_array($criteria->select)){
            $criteria->select=array_unique(array_merge($criteria->select,self::$autoLoadAttributes));
        }
        
        $criteria->condition = 'recipeId=:recipeId';
        $criteria->params = array(':recipeId'=>$recipeId);
        if(empty($criteria->order)) {
            $criteria->order = 'helpful desc, id asc';
        }

        return self::loadObjects($criteria);
    }
    
    public static function loadObjectsByUserId($userId, $options=array())
    {
        if($options instanceof CDbCriteria) {
            $criteria=&$options;            
        }
        else {
            $criteria=new CDbCriteria($options);
        }

        if(is_array($criteria->select)){
            $criteria->select=array_unique(array_merge($criteria->select,self::$autoLoadAttributes));
        }

        $criteria->condition = 'userId=:userId';
        $criteria->params = array(':userId'=>$userId);
        if(empty($criteria->order)) {
            $criteria->order = 'id desc';
        }
                
        return self::loadObjects($criteria);
    }

    public static function loadObject($criteria=array())
    {
        $criteria['limit']=1;                                 
        return array_shift(self::loadObjects($criteria));
    }
    
    public static function loadObjects($criteria=array())
    {
        return self::model()->findAll($criteria);
    }

    public static function updateObjectCountersById($id,$counters)
    {
        return self::updateObjectCounters(
            $counters,
            array('condition'=>'id=:id', 'params'=>array(':id'=>$id))
        );
    }

    public static function updateObjectCounters($counters, $criteria=array())
    {
        return self::model()->updateCounters($counters, $criteria);
    }

    public static function saveObject(&$object, $attributes=null)
    {
        if(is_array($attributes))
            $object->_saveAttributes=array_flip($attributes);
        else
            $object->_saveAttributes=$attributes;

        if($object->getIsNewRecord()){
            $ret=self::createObject($object, $attributes);
        }
        else {
            $ret=$object->save(true, $attributes);
        }

        unset($object->_saveAttributes);
        return $ret;        
    }
    
    public static function deleteObject(&$object)
    {
        $transaction=Yii::app()->db->beginTransaction();
        try {
            if(!$object->delete()) {
                $transaction->rollBack();
                return false;
            }
            
            CommentHelpVote::deleteObjectByCommentId($object->id);
            Kitchen::updateObjectCountersById($object->userId, array('commentNum'=>-1));
            Recipe::updateObjectCountersById($object->recipeId, array('commentNum'=>-1));
            $transaction->commit();
            return true;
        }
        catch(Exception $e){
            $transaction->rollBack();
            throw $e;
        }
    }
    
    protected static function createObject(&$object, $attributes=null)
    {
        $transaction=Yii::app()->db->beginTransaction();
        try {
            if(!$object->save(true, $attributes))
                return false;

            Kitchen::updateObjectCountersById($object->userId, array('commentNum'=>1));
            Recipe::updateObjectCountersById($object->recipeId, array('commentNum'=>1));
            $transaction->commit();
            return true;
        }
        catch(Exception $e){
            $transaction->rollBack();
            $object->steps=array();
            throw $e;
        }
    }    
    

    /********************************************************************
    *  Below are object & AR required functions
    *********************************************************************/

	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	public function tableName()
	{
		return 'Comment';
	}

	public function rules()
	{
		return array(
			array('recipeId, userId, userName, content', 'required'),
			array('userId, helpful, createTime', 'numerical', 'integerOnly'=>true),
			array('content', 'WStringValidator', 'min'=>self::CONTENT_MIN_LEN, 'max'=>self::CONTENT_MAX_LEN),
		);
	}

	public function attributeLabels()
	{
		return array(
			'id' => 'Id',
			'recipeId' => 'Recipe',
			'userId' => 'User',
			'userName' => 'User Name',
			'content' => 'Content',
			'helpful' => 'Helpful',
			'createTime' => 'Create Time',
		);
	}
    
    protected function isSaveAttribute($name)
    {
        if(is_array($this->_saveAttributes))
            return array_key_exists($name,$this->_saveAttributes);
        return true;
    }
    
    protected function beforeValidate()
    {
        if($this->isNewRecord)
            $this->createTime=time();
        return true;
    }    
}